package elijah.base.adapter;

import android.annotation.SuppressLint;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import elijah.base.AppBase;
import elijah.base.utils.ClassUtils;
import elijah.base.utils.Toasts;


public abstract class BaseAdapter<T, V extends ViewBinding> extends RecyclerView.Adapter<BaseHolder<T, V>> {
    private List<T> data;
    private final int[] bgColors;


    private OnItemClickListener onItemClickListener;

    public BaseAdapter<T, V> setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
        return this;
    }

    public BaseAdapter() {
        this(new ArrayList<>(), null);
    }

    public BaseAdapter(List<T> data) {
        this(data, null);

    }

    public BaseAdapter(int[] bgColors) {
        this(new ArrayList<>(), bgColors);
    }

    public BaseAdapter(List<T> data, int[] bgColors) {
        this.data = data;
        this.bgColors = bgColors;


    }

    @SuppressLint("NotifyDataSetChanged")
    public BaseAdapter<T, V> setData(List<T> data) {
        if (data == null) data = new ArrayList<>();
        this.data = data;
        notifyDataSetChanged();
        return this;
    }

    public BaseAdapter<T, V> addData(List<T> addData) {
        if (data == null) data = new ArrayList<>();
        this.data.addAll(addData);
        notifyItemRangeInserted(data.size(), addData.size());
        return this;
    }

    public BaseAdapter<T, V> add(T item) {
        if (data == null) data = new ArrayList<>();
        this.data.add(item);
        notifyItemInserted(data.size());
        return this;
    }

    public List<T> getData() {
        return data;
    }

    public T getItem(int position) {
        return position >= 0 & position < data.size() ? data.get(position) : null;
    }


    @NonNull
    @Override
    public BaseHolder<T, V> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        V v = (V) ClassUtils.getViewBinding(getClass(), 1, parent);
        T t;
        try {
            t = (T) ClassUtils.getParamClass(getClass(), 0).newInstance();
        } catch (IllegalAccessException | InstantiationException e) {
            throw new RuntimeException(e);
        }
        return getBaseHolder(v, t);

    }

    @NonNull
    protected BaseHolder<T, V> getBaseHolder(V v, T t) {
        return new BaseHolder<T, V>(v, t) {
        };
    }


    public abstract void setData(V holder, T value, int position);


    @Override
    public void onBindViewHolder(@NonNull BaseHolder<T, V> holder, int position) {
        try {
            if (bgColors != null && bgColors.length > 0) {
                holder.itemView.setBackgroundColor(bgColors[position % bgColors.length]);
            }
            if (onItemClickListener != null) {
                holder.itemView.setOnClickListener(v -> onItemClickListener.onItemClick(v, position));
            }
            T value = position < data.size() ? data.get(position) : null;
            if (holder.getDataBinding() != null) {
                holder.getDataBinding().bindData(value);
            }
            setData(holder.getBinding(), value, position);

        } catch (Exception e) {
            e.printStackTrace();
            Toasts.showErrorToast("数据解析异常：" + e.getMessage());
        }


    }


    @Override
    public int getItemCount() {
        return data.size();
    }


    public void removeIndex(int position) {
        if (position >= data.size() || position < 0) return;
        data.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, data.size() - position);
    }

    public void remove(T t) {

        removeIndex(data.indexOf(t));
    }

    public void removeRange(int start, int end) {
        if (start >= data.size() || end < start) return;
        if (start == end) {
            removeIndex(start);
            return;
        }

        for (int i = 0; i < end - start; i++) {
            data.remove(end - 1 - i);
        }
        notifyItemRangeRemoved(start, end);
    }

    public void clearAll() {
        int len = data.size();
        data.clear();
        notifyItemRangeRemoved(0, len);

    }

    ;


    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

}
